package com.jl.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jl.enums.RoomAction;
import com.jl.model.niuniu.enums.PeopleNumber;
import com.jl.model.req.RoomIntoReq;
import com.jl.model.resp.RoomInfoResp;
import com.jl.model.socket.RoomDetail;
import com.jl.utils.CommonUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Slf4j
public class RoomInfoService {

    @Resource
    private RedisTemplate redisTemplate;

    private String percentage = "niuniu_percentage";


    public void setRoomDetail(Object object){
        try {
            Object id = PropertyUtils.getProperty(object, "id");
            Object type = PropertyUtils.getProperty(object, "gameType");
            if (id!=null && type!=null){
                redisTemplate.opsForValue().set(id+"_"+type+"_detail", JSONObject.toJSONString(object));
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    public String getRoomDetail(Integer id,String type){
        Object o = redisTemplate.opsForValue().get(id + "_" + type + "_detail");
        if (o!=null){
            return o.toString();
        }
        return null;
    }

    public void deleteRoom(Integer id,String type){
        redisTemplate.delete(id + "_" + type + "_detail");
    }

    public void setRoomResult(Integer roomId, Collection<?> list){
        redisTemplate.opsForHash().put("result",roomId+"_result",JSONObject.toJSONString(list));
    }

    public <T> void deleteRoomResult(Integer roomId,Integer userId,Class<T> t){
        Collection<T> roomResult = getRoomResult(roomId, t);
        T ob = null;
        for (T t1 : roomResult) {
            try {
                String id = PropertyUtils.getProperty(t1, "id").toString();
                if (id.equals(String.valueOf(userId))){
                    ob = t1;
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        roomResult.remove(ob);
        setRoomResult(roomId,roomResult);
//        redisTemplate.opsForHash().delete("result",roomId+"_result");
    }

    public <T> Collection<T> getRoomResult(Integer roomId,Class<T> t){
        Object result = redisTemplate.opsForHash().get("result", roomId + "_result");
        if (result!=null){
            List<T> ts = JSONArray.parseArray(result.toString(), t);
            return ts;
        }
        return null;
    }

    public Integer getGameId(){
        int id;
        Object game_id = redisTemplate.opsForValue().get("game_id");
        if (game_id==null){
            id = 1;
        }else {
            id = Integer.valueOf(game_id.toString())+1;
        }
        redisTemplate.opsForValue().set("game_id",id);
        return id;
    }

    /*
    生成座位号
     */
    public Integer genSeatNumb(RoomIntoReq roomIntoReq, RoomDetail roomDetail, String peopleNumber,Class<? extends Enum> clazz){
        Integer numb = Integer.valueOf(CommonUtils.getEnumDescById(clazz, peopleNumber, "getValue"));
        ConcurrentHashMap<Integer, Integer> userSeat = roomDetail.getUserSeat();
        if (userSeat.get(roomIntoReq.getUserId())==null){ //如果没在游戏中 则分配座位, 否则座位不变
            int seat=1;
            if (userSeat.size()==numb){
                return null;
            }
            if (userSeat.size()>0){
                for1:
                for (int i=1 ;i<=numb;i++){
                    for (Integer integer : userSeat.values()) {
                        if (i==integer){
                            continue for1;
                        }
                    }
                    seat=i;
                    break ;
                }
            }
            userSeat.put(roomIntoReq.getUserId(),seat);
            return seat;
        }else {
            return userSeat.get(roomIntoReq.getUserId());
        }
    }

    /*
    发送给房间所有人
     */
    public void sendChanel(RoomDetail roomDetail, String message, RoomInfoResp roomInfoResp) {
        roomDetail.getUserChanel().forEach((key,value)->{
            roomInfoResp.setUserId(key);
            roomInfoResp.setActionValue(message);
            value.channel().writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(roomInfoResp)));
            log.info("发送的信息:{}",roomInfoResp);
        });
        roomDetail.getUserChanelWatcher().forEach((key,value)->{
            roomInfoResp.setUserId(key);
            roomInfoResp.setActionValue(message);
            value.channel().writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(roomInfoResp)));
            log.info("发送的信息:{}",roomInfoResp);
        });
    }

    /*
    发送错误信息
     */
    public void sendErrorMessage(RoomIntoReq roomIntoReq, RoomAction niuAction, ChannelHandlerContext channelHandlerContext){
        RoomInfoResp roomInfoResp = new RoomInfoResp();
        BeanUtils.copyProperties(roomIntoReq,roomInfoResp);
        roomInfoResp.setAction(niuAction.getId());
        roomInfoResp.setActionValue(niuAction.getDesc());
        channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(roomInfoResp)));
    }

    /*
    退出房间清除数据
     */
    public void quit(RoomIntoReq roomIntoReq,RoomDetail roomDetail,ChannelHandlerContext channelHandlerContext){
        roomDetail.getUserChanelWatcher().remove(roomIntoReq.getUserId());
        roomDetail.getUserChanel().remove(roomIntoReq.getUserId());
        roomDetail.getUserInfo().remove(roomIntoReq.getUserId());
        roomDetail.getPlayer().getChannelGroup().remove(channelHandlerContext.channel());
        roomDetail.getWatcher().getChannelGroup().remove(channelHandlerContext.channel());
        roomDetail.getUserSeat().remove(roomIntoReq.getUserId());
    }

    /*
    抽成
     */
    public BigDecimal getPercentage(){
        Object o = redisTemplate.opsForValue().get(percentage);
        if (o!=null){
            return new BigDecimal(o.toString());
        }
        return null;
    }

    public void addPercentage(BigDecimal add){
        Object percentage_total = redisTemplate.opsForValue().get("percentage_total");
        if (percentage_total==null){
            redisTemplate.opsForValue().set("percentage_total","0");
            percentage_total = new BigDecimal(0);
        }else {
            percentage_total = new BigDecimal(percentage_total.toString()).add(add);
        }
        redisTemplate.opsForValue().set("percentage_total",percentage_total.toString());
    }

    /*
    保存上庄信息
     */
    public void setSzInfo(Integer roomId,Collection<?> list){
        redisTemplate.opsForHash().put("sz",roomId+"_sz",JSONObject.toJSONString(list));
    }

    public <T> List<T> getSzInfo(Integer roomId,Class<T> tClass){
        Object sz = redisTemplate.opsForHash().get("sz", roomId + "_sz");
        if (sz!=null){
            return JSONArray.parseArray(sz.toString(), tClass);
        }
        return null;
    }

    public String getNotice(){
        Object notice = redisTemplate.opsForValue().get("notice");
        if (notice!=null){
            return notice.toString();
        }
        return null;
    }
}
